package club.pchome.common.util;

import club.pchome.common.constant.SystemConstant;
import club.pchome.common.entity.CheckResult;

import com.sun.org.apache.xml.internal.security.exceptions.Base64DecodingException;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import io.jsonwebtoken.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.SignatureException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author Watler
 * @apiNote  jwt加密和解密的工具类
 * @date 2017年11月24日
 */
@Component
public class JwtUtils {

    private static final String JWT_NAME = "WATLER.PENG";

	/**
	 * 签发JWT
	 * @Author  科帮网 
	 * @param id
	 * @param subject 主题,可以是JSON数据 尽可能少
	 * @param ttlMillis
	 * @return  String
	 * @Date	2017年11月24日
	 * 2017年11月24日  张志朋  首次创建
	 *
	 */
	public String createJWT(String id, String subject, long ttlMillis) throws Base64DecodingException {
		SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
		long nowMillis = System.currentTimeMillis();
		Date now = new Date(nowMillis);
		SecretKey secretKey = generalKey();
		JwtBuilder builder = Jwts.builder()
				.setId(id)
				.setSubject(subject)
				.setIssuer(JWT_NAME)
				.setIssuedAt(now)
				.signWith(signatureAlgorithm, secretKey);

		if (ttlMillis >= 0) {
			long expMillis = nowMillis + ttlMillis;
			Date expDate = new Date(expMillis);
			// 过期时间
			builder.setExpiration(expDate);
		}

		return builder.compact();
	}

	/**
	 * 验证JWT
	 * @param jwtStr
	 * @return
	 */
	public static CheckResult validateJWT(String jwtStr) {
		CheckResult checkResult = new CheckResult();
		Claims claims = null;
		try {
			claims = parseJWT(jwtStr);
			checkResult.setSuccess(true);
			checkResult.setClaims(claims);
		} catch (ExpiredJwtException e) {
			checkResult.setErrCode(SystemConstant.JWT_ERRCODE_EXPIRE);
			checkResult.setSuccess(false);
		} catch (Exception e) {
			checkResult.setErrCode(SystemConstant.JWT_ERRCODE_FAIL);
			checkResult.setSuccess(false);
		}
		return checkResult;
	}
	
	private static SecretKey generalKey() throws Base64DecodingException {
		byte[] encodedKey = Base64.decode(SystemConstant.JWT_SECERT);
		return new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
	}
	
	/**
	 * 
	 * 解析JWT字符串
	 * @param jwt
	 * @return
	 * @throws Exception
	 */
	public static Claims parseJWT(String jwt) throws Exception {
		SecretKey secretKey = generalKey();
		return Jwts.parser()
			.setSigningKey(secretKey)
			.parseClaimsJws(jwt)
			.getBody();
	}

	public static final SimpleDateFormat FMT_FN = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	public static void main(String[] args) throws Exception {
		JwtUtils util=   new JwtUtils();
		String ab=util.createJWT("545" , "xiaohong" , 60000 );
//		System.out.println(ab);
		//eyJhbGciOiJIUzI1NiJ9.eyJ1aWQiOiJEU1NGQVdEV0FEQVMuLi4iLCJzdWIiOiJ7aWQ6MTAwLG5hbWU6eGlhb2hvbmd9IiwidXNlcl9uYW1lIjoiYWRtaW4iLCJuaWNrX25hbWUiOiJEQVNEQTEyMSIsImV4cCI6MTUxNzgzNTE0NiwiaWF0IjoxNTE3ODM1MDg2LCJqdGkiOiJqd3QifQ.ncVrqdXeiCfrB9v6BulDRWUDDdROB7f-_Hg5N0po980
//		System.out.println(validateJWT(ab).getClaims());
		Claims c = parseJWT(ab);//注意：如果jwt已经过期了，这里会抛出jwt过期异常。
		System.out.println(validateJWT(ab).getErrCode());//jwt
//		System.out.println(FMT_FN.format(c.getIssuedAt().getTime()));//Mon Feb 05 20:50:49 CST 2018
//		System.out.println(c.getSubject());//{id:100,name:xiaohong}
//		System.out.println(c.getIssuer());//null
//		System.out.println(c.get("userInfo", String.class));//DSSFAWDWADAS...
	}

}
